﻿
using com.iot.core.boot.configuration;
using com.iot.core.infrastructure;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.GridFS;
 using System.Runtime.CompilerServices;
 

namespace com.iot.core.mongo
{
    public class MongoDBHelper
    {
        IMongoClient mongoClient;
        IMongoDatabase mongoDatabase;
        IMongoCollection<MongoCache> mongoCacheCollection;
        private MongoDBHelper()
        {
            var dbcfg = Singleton<AppSettings>.Instance.Get<MongoSetting>();
            MongoClientSettings set = new MongoClientSettings();
            var servers = new List<MongoServerAddress>();

            set.Servers = servers;
            set.ReplicaSetName = dbcfg.ReplicaSetName;
            int TimeOut = dbcfg.ConnectTimeout;
            set.ConnectTimeout = new TimeSpan(0, 0, 0, TimeOut, 0);//设置超时时间为5秒

            // set.ReadPreference = new ReadPreference(ReadPreferenceMode.SecondaryPreferred);             

            var url = dbcfg.Address + "?serverSelectionTimeoutMS=3000&connectTimeoutMS=3000&socketTimeoutMS=30000";
            mongoClient = new MongoClient(url ); 
            mongoDatabase=mongoClient.GetDatabase(dbcfg.Database);

             mongoCacheCollection = mongoDatabase.GetCollection<MongoCache>("MongoCache");


            var indexKeysDefinition = Builders<MongoCache>.IndexKeys.Ascending("ExpireAt");
            var indexOptions = new CreateIndexOptions {
                ExpireAfter = new TimeSpan(0, 0, 0)
            };
            var indexModel = new CreateIndexModel<MongoCache>(indexKeysDefinition, indexOptions);
            try
            {
                mongoCacheCollection.Indexes.CreateOne(indexModel);
            }
            catch (Exception ex) 
            { 
            }


        }
        [MethodImpl(MethodImplOptions.Synchronized)]
         static MongoDBHelper Create()
        {
            //create NopEngine as engine
            var m = Singleton<MongoDBHelper>.Instance ?? 
                (Singleton<MongoDBHelper>.Instance = new MongoDBHelper());

            return m;
        }
        public static MongoDBHelper Current
        {
            get
            {
                if (Singleton<MongoDBHelper>.Instance == null)
                {
                    Create();
                }

                return Singleton<MongoDBHelper>.Instance;
            }
        }

         
        public void InsertOne<T>(T entity,string tname="") where T : class
        {
            if (string.IsNullOrEmpty(tname))
            {
                tname=(typeof(T).Name);
            }
            var c=mongoDatabase.GetCollection<T>(tname);
            c.InsertOne(entity);
        }
        public IMongoCollection<T> GetCollection<T>(string tname = "")
        {
            if (string.IsNullOrEmpty(tname))
            {
                tname = (typeof(T).Name);
            }
            var c = mongoDatabase.GetCollection<T>(tname);
            return c;
        }
        public GridFSBucket NewBucket()
        {
            var bucket = new GridFSBucket(mongoDatabase);
            return bucket;
        }
        public void Set(string key, string V, TimeSpan dt)
        {
             
            var m = mongoCacheCollection.AsQueryable().Where(a => a.Id == key).FirstOrDefault();
             
            if (m==null)
            {
                m = new MongoCache
                {
                    Id = key,
                    V = V,
                    ExpireAt = DateTime.Now.AddTicks(dt.Ticks),
                    Crt_Dt = DateTime.Now
                };
                mongoCacheCollection.InsertOne(m);

            }
            else
            {

                var filter = Builders<MongoCache>.Filter.Where(a => a.Id == key);


                var update = Builders<MongoCache>.
                    Update.Set(a => a.V ,V)
                    .Set(a => a.ExpireAt, DateTime.Now.AddTicks(dt.Ticks))
                    ;
                mongoCacheCollection.UpdateOne(filter, update);
            }
        }
    }

}
